package cn.tit.ias.controller.pc;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.ObjectUtils.Null;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;


import cn.tit.ias.aop.MethodLog;
import cn.tit.ias.entity.UserInfo;
import cn.tit.ias.service.DepartInfoService;
import cn.tit.ias.service.DicUserRoleInfoService;
import cn.tit.ias.service.UserInfoService;
import cn.tit.ias.util.controllerresponse.ControllerResponse;
import cn.tit.ias.util.controllerresponse.ControllerResponseFactory;
import cn.tit.ias.util.security.CaptchaGenerator;
import cn.tit.ias.util.security.MD5Util;
import cn.tit.ias.util.shiro.ValidateCodeFilter;

/**
 * 
 * 
 * @Description:PC端用户管理
 * @author: 隔山海
 * @date: 2019年6月16日 上午9:36:15
 *
 */
@Controller
@RequestMapping("")
public class PCUserInfoController {
	private static final String SUPER_ADMIN_ROLE = "超级管理员";
	private static final String INVENTORY_ADMIN_ROLE = "盘点员";
	@Autowired
	private UserInfoService userInfoService;
	@Autowired
	private DicUserRoleInfoService userRoleService;
	
	@Autowired
	private DepartInfoService departService;
	/** 登陆页面 */
	
	@RequestMapping("/mainPage")
	public String mainPage() {
		return "mainPage";
	}
	
	@RequestMapping("forcedissonionPassword")
	public String forcedissonionPassword() {
		return "forcedissonionPassword";
	}

	/**
	 * 
	 * @Title: login @Description: 登陆用户的验证 @param: @param
	 *         userInfo @param: @return 返回一个 Map 对象，其中包含登陆操作的结果 @return:
	 *         Map<String,Object> @throws
	 */
	@RequestMapping(value = "login", method = RequestMethod.POST)
	@ResponseBody
	@MethodLog(name = "用户模块", option = "登陆")
	public Map<String, Object> login(@RequestBody Map<String, Object> userInfo, HttpServletRequest request) {
		/** 自定义的map对象，用于前后端json传输 */
		ControllerResponse response = ControllerResponseFactory.newInstance();
		String result = ControllerResponse.RESPONSE_RESULT_ERROR;
		String errorMsg = "";
		
		// 用户登陆的信息
		String id = (String) userInfo.get("id");
		String password = (String) userInfo.get("password");
		String ip = (String) userInfo.get("ip");
		String checkCode = (String) userInfo.get("checkCode");
		Subject subject = SecurityUtils.getSubject();
		Session session = subject.getSession();
		// 验证验证码
		String validateCode = (String) session.getAttribute("checkCode");
		if(!checkCode.toUpperCase().equals(validateCode)){
			result=ControllerResponse.RESPONSE_RESULT_ERROR;
			errorMsg = "-1";	//验证码错误
		}else {
			// shiro验证
			password = MD5Util.MD5(password);
			UsernamePasswordToken token = new UsernamePasswordToken(id,password,checkCode);
			try {
				//登陆成功，添加ip到shiro的session域
				subject.login(token);
				System.out.println(token);
				UserInfo loginUser = (UserInfo) session.getAttribute("loginUser");
				int roleId = loginUser.getUserRoleId();
				String role = userRoleService.getObject(roleId).getUserRoleName();
				if(role.equals(INVENTORY_ADMIN_ROLE)){
					errorMsg="-2";
					result = ControllerResponse.RESPONSE_RESULT_ERROR;
				}else{
					session.setAttribute("ip", ip);
					errorMsg="1";
					result = ControllerResponse.RESPONSE_RESULT_SUCCESS;
				}
				
			} catch (Exception  e) {
				System.out.println("登陆失败: " + e.getMessage());
				errorMsg = "0";
				result = ControllerResponse.RESPONSE_RESULT_ERROR;
			}
		}
		/** 以json格式响应的信息 */
		response.setResponseResult(result);
		response.setResponseMsg(errorMsg);
		System.out.println(response.generateResponse());
		/** 返回一个map对象json格式 */
		return response.generateResponse();
	}

	/**
	 * 
	 * @Title: logout @Description: 退出登陆 @param: 返回一个 Map 对象， @return:
	 *         Map<String,Object> @throws
	 */
	@RequestMapping(value = "logout", method = RequestMethod.GET)
	@ResponseBody
	public Map<String, Object> logout() {
		ControllerResponse response = ControllerResponseFactory.newInstance();
		Subject subject = SecurityUtils.getSubject();
		if(subject.isAuthenticated()){
			subject.logout();
		}
		String result = "确定要退出";
		response.setResponseResult(result);
		return response.generateResponse();
	}

	/**
	 *
	 * @Title: listUserInfo @Description: 查询部门的所有用户盘点员 departNum @param: @param
	 *         offset 如有多条记录时分页的偏移值
	 * @param: @param
	 *             limit 如有多条记录时分页的大小
	 * @param: @return
	 * @return:Map<String,Object> @throws
	 * 
	 */
	@SuppressWarnings("null")
	@RequestMapping(value = "listUserInfo", method = RequestMethod.GET)
	@ResponseBody
	//@MethodLog(name = "用户模块", option = "查询用户信息")
	public Map<String, Object> listUserInfo( @RequestParam("offset") int offset,
			@RequestParam("limit") int limit,@RequestParam("depart")String depart) {

		ControllerResponse response = ControllerResponseFactory.newInstance();
		String result = ControllerResponse.RESPONSE_RESULT_ERROR;
		// 存放查询出的来的数据集 
		List<UserInfo> rows = null;
		// 查询出来的数据个数 
		int total = 0;
		// 要查询的部门编号
		String departNum = null;
		// 封装返回给前端的数据
		List<Map<String, Object>> listFinalResult = new ArrayList<>();
		
		
		// 通过shiro获取当前登录的对象
		Subject currentUser = SecurityUtils.getSubject();
		Session session = currentUser.getSession();
		// 获取session域中当前登陆用户
		UserInfo loginUser = (UserInfo) session.getAttribute("loginUser");
		// 获取当前用户的角色
		String userRole = (String) session.getAttribute("loginUserRole");
		
		// 判断用户角色
		if(userRole.equals(SUPER_ADMIN_ROLE)){
			// 当部门为空时
			if (depart.equals("")) {
				response.setResponseResult(ControllerResponse.RESPONSE_RESULT_SUCCESS);
				response.setObjectInfo("rows", listFinalResult);
				response.setResponseTotal(0);
				return response.generateResponse();
			}
			departNum = departService.getDepartByName(depart).getDepartNum();
		}else{
			departNum = loginUser.getDepartNum();
		}
		
		// 分页查询部门中的用户
		Map<String, Object> queryResult = userInfoService.listObjectByPage(offset, limit, departNum);
		if (queryResult != null) {
			rows = (List<UserInfo>) queryResult.get("data");
			Iterator<UserInfo> iterator = rows.iterator();
			while (iterator.hasNext()) {
				Map<String, Object> finalResult = new HashMap<>();
				UserInfo row = iterator.next();
				finalResult.put("userCount", row.getUserCount());
				finalResult.put("userName", row.getUserName());
				finalResult.put("userRole", userRoleService.getObject(row.getUserRoleId()).getUserRoleName());
				listFinalResult.add(finalResult);
			}
			total = (int) queryResult.get("total");
		}
		
		// 查询成功封装返回数据
		result = ControllerResponse.RESPONSE_RESULT_SUCCESS;
		response.setResponseResult(result);
		response.setObjectInfo("rows", listFinalResult);
		response.setResponseTotal(total);
		return response.generateResponse();
	}

	/**
	 * 
	 * @Title: addUserInfo @Description: 添加一条用户盘点员信息 @param: @param
	 *         userInfo @param: @return @return: Map<String,Object> @throws
	 */
	@RequestMapping(value = "addUserInfo", method = RequestMethod.POST)
	@ResponseBody
	@MethodLog(name = "用户模块", option = "添加用户信息")
	public Map<String, Object> addUserInfo(@RequestBody Map<String, Object> userInfo, HttpServletRequest request) {

		/** 初始化response */
		ControllerResponse response = ControllerResponseFactory.newInstance();

		/** 接收前端传来的参数 */
		String userCount = (String) userInfo.get("userCount");
		String userName = (String) userInfo.get("userName");
		String userPassward = "123";
		String userRole = (String) userInfo.get("userRole");
		String userDepartName = (String) userInfo.get("userDepart");
		System.out.println(userDepartName);
		
		if(userCount==null || userName == null ||userCount.equals("")||userName.equals("")){
			response.setResponseResult(ControllerResponse.RESPONSE_RESULT_ERROR);
			return response.generateResponse();
		}
		
		// 通过shiro获取当前登录的对象
		Subject currentUser = SecurityUtils.getSubject();
		Session session = currentUser.getSession();
		// 获取session域中当前登陆用户
		UserInfo loginUser = (UserInfo) session.getAttribute("loginUser");
		// 获取当前用户的角色
		String loginUserRole = (String) session.getAttribute("loginUserRole");
		String userDepartNum = null;
		
		// 根据登陆用户角色，选择添加用户的部门 超级管理员是从前台获取部门；普通管理员是从登陆这的session中获取
		if(loginUserRole.equals(SUPER_ADMIN_ROLE)){
			if(userDepartName==null || userDepartName.equals("")){
				response.setResponseResult(ControllerResponse.RESPONSE_RESULT_ERROR);
				return response.generateResponse();
			}
			userDepartNum = departService.getDepartByName(userDepartName).getDepartNum();
		}else{
			userDepartNum = loginUser.getDepartNum();
		}
		
		try {
			/** 获取用户角色id */
			int userRoleId = userRoleService.getUserByName(userRole).getUserRoleId();
			System.out.println(userRoleId);
			/** 验证用户是否存在 */
			try {
				if (userInfoService.getObject(userCount).getUserCount().equals(userCount)) {
					System.out.println(userCount);
					response.setResponseResult("该账户已存在");
				}
			} catch (Exception e) {
				/** 将前端获取数据封装成UserInfo对象 */
				UserInfo addUser = new UserInfo();
				userPassward = MD5Util.MD5(userPassward);
				System.out.println(userPassward);
				addUser.setUserCount(userCount);
				addUser.setDepartNum(userDepartNum);
				addUser.setUserName(userName);
				addUser.setUserPassward(userPassward);
				addUser.setUserRoleId(userRoleId);
				int result = userInfoService.addObject(addUser);
				// System.out.println(userInfo);
				if (result == 1) {
					response.setResponseResult(ControllerResponse.RESPONSE_RESULT_SUCCESS);
				} else {
					response.setResponseResult(ControllerResponse.RESPONSE_RESULT_ERROR);
				}
			}
		} catch (NullPointerException e) {
			response.setResponseResult("未登录用户");
		}
		return response.generateResponse();
	}

	/**
	 * 
	 * @Title: deleteUserInfo @Description: 删除一条用户盘点员的信息 @param: @param
	 *         userInfoNum @param: @return @return: Map<String,Object> @throws
	 */
	@RequestMapping(value = "deleteUserInfo", method = RequestMethod.GET)
	@ResponseBody
	@MethodLog(name = "用户模块", option = "删除用户信息")
	public Map<String, Object> deleteUserInfo(@RequestParam("userCount") String userInfoNum) {

		/** 初始化response */
		ControllerResponse response = ControllerResponseFactory.newInstance();
		try {
			int deleteResult = userInfoService.deleteObject(userInfoNum);
			if (deleteResult == 1) {

				/** 删除操作成功 */
				response.setResponseResult(ControllerResponse.RESPONSE_RESULT_SUCCESS);
			} else

				/** 删除操作失败 */
				response.setResponseResult(ControllerResponse.RESPONSE_RESULT_ERROR);
		} catch (Exception e) {
			response.setResponseResult(ControllerResponse.RESPONSE_RESULT_ERROR);
		}
		return response.generateResponse();
	}

	/**
	 * 
	 * @Title: updateUserInfo @Description: 更新用户盘点员的信息 @param: @param
	 *         userInfo @param: @return @return: Map<String,Object> @throws
	 */
	@RequestMapping(value = "updateUserInfo", method = RequestMethod.POST)
	@ResponseBody
	@MethodLog(name = "用户模块", option = "修改用户信息")
	public Map<String, Object> updateUserInfo(@RequestBody Map<String, Object> userInfo) {

		ControllerResponse response = ControllerResponseFactory.newInstance();
		/** 接收前端传来的参数 */
		String userCount = (String) userInfo.get("userCount");
		String userName = (String) userInfo.get("userName");
		String userPassward = (String) userInfo.get("userPassward");
		String userRole = (String) userInfo.get("userRole");
		try {
			//userPassward = MD5Util.MD5(userPassward);
			/** 封装数据为user对象 */
			UserInfo user = new UserInfo();
			user.setUserCount(userCount);
			user.setUserName(userName);
			user.setUserPassward(userPassward);
			user.setUserRoleId(userRoleService.getUserByName(userRole).getUserRoleId());

			/** 修改操作 */
			userInfoService.updateObject(user);
			response.setResponseResult(ControllerResponse.RESPONSE_RESULT_SUCCESS);
		} catch (Exception e) {
			/*** 修改失败 */
			response.setResponseResult(ControllerResponse.RESPONSE_RESULT_ERROR);
		}
		return response.generateResponse();
	}

	/**
	 * 获取图形验证码 将返回一个包含4位字符（字母或数字）的图形验证码，并且将图形验证码的值设置到用户的 session 中
	 *
	 * @param time
	 *            时间戳
	 * @param response
	 *            返回的 HttpServletResponse 响应
	 */
	@RequestMapping(value = "checkCode/{time}", method = RequestMethod.GET)
	public void getCheckCode(@PathVariable("time") String time, HttpServletResponse response,
			HttpServletRequest request) {

		BufferedImage checkCodeImage = null;
		String checkCodeString = null;

		// 获取图形验证码
		Map<String, Object> checkCode = CaptchaGenerator.generateCaptcha();

		if (checkCode != null) {
			checkCodeString = (String) checkCode.get("captchaString");
			checkCodeImage = (BufferedImage) checkCode.get("captchaImage");
		}

		if (checkCodeString != null && checkCodeImage != null) {
			try (ServletOutputStream outputStream = response.getOutputStream()) {
				// 设置 Session
				//HttpSession session = request.getSession();
				Subject subject = SecurityUtils.getSubject();
				Session session = subject.getSession();
				session.setAttribute("checkCode", checkCodeString);

				// 将验证码输出
				ImageIO.write(checkCodeImage, "png", outputStream);

				response.setHeader("Pragma", "no-cache");
				response.setHeader("Cache-Control", "no-cache");
				response.setDateHeader("Expires", 0);
				response.setContentType("image/png");
			} catch (IOException e) {

			}
		}
	}
	
	@RequestMapping(value = "passwordModify",method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> passwordModify(@RequestBody Map<String, Object> passwordInfo,
            HttpServletRequest request) {
		// 初始化response
		ControllerResponse response = ControllerResponseFactory.newInstance();
		
		// 获取用户 ID
        HttpSession session = request.getSession();
		UserInfo loginUser = (UserInfo) session.getAttribute("loginUser");
		String userCount = loginUser.getUserCount();
		try {
			Map<String, Object> result = userInfoService.passwordModify(userCount, passwordInfo);
			
			response.setResponseMsg((String)result.get("msg"));
			response.setResponseResult((String)result.get("result"));
		} catch (Exception e) {
			response.setResponseMsg("error");
			response.setResponseResult(ControllerResponse.RESPONSE_RESULT_ERROR);
		}
		return response.generateResponse();
	}
	
	/*强制修改密码**/
	@RequestMapping(value = "Forced", method = RequestMethod.POST)
	@ResponseBody
	public Map<String,Object> Forced(@RequestBody Map<String,Object> password,HttpServletRequest request){
		// 初始化response
		ControllerResponse response = ControllerResponseFactory.newInstance();
		// 获取用户 ID
        HttpSession session = request.getSession();
        UserInfo loginUser=new UserInfo();
        try {
        	loginUser = (UserInfo) session.getAttribute("loginUser");
		} catch (Exception e) {
			loginUser=null;
			System.out.println("获取登陆者信息异常");
		}
		String msg="";
		String result="";
		if(loginUser==null) {
			result=ControllerResponse.RESPONSE_RESULT_ERROR;
			msg="登陆状态异常，请重新登陆";
		}else {
			String oldpassword = (String) password.get("oldpassword");
			String newpassword = (String) password.get("newpassword");
			try{
				//验证原密码是否正确
				if(MD5Util.MD5(oldpassword).equals(loginUser.getUserPassward())){
					//原密码正确
					try {
						UserInfo userInfo=new UserInfo();
						userInfo.setUserCount(loginUser.getUserCount());
						userInfo.setUserPassward(MD5Util.MD5(newpassword));
						userInfoService.updateObject(userInfo);
						result=ControllerResponse.RESPONSE_RESULT_SUCCESS;
						msg="修改成功";
						//清空session域中的所有信息
						try {
							System.out.println("清空成功");
							session.setAttribute("loginUser", null);
						} catch (Exception e) {
							System.out.println("清空失败");
						}
					} catch (Exception e) {
						msg="修改失败";
						result=ControllerResponse.RESPONSE_RESULT_ERROR;
					}
				}else {
					//原密码不正确
					msg="原密码不正确";
					result=ControllerResponse.RESPONSE_RESULT_ERROR;
				}
			}catch (Exception e) {
				result=ControllerResponse.RESPONSE_RESULT_ERROR;
			}
		}
		
		System.out.println(result);
		System.out.println(msg);
		response.setResponseResult(result);
		response.setResponseMsg(msg);
		return response.generateResponse();
	}

}
